package com.ErpCoreWeb.View;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ErpCoreModel.Base.AccessType;
import com.ErpCoreModel.Base.CUser;
import com.ErpCoreModel.Framework.CBaseObject;
import com.ErpCoreModel.Framework.CBaseObjectMgr;
import com.ErpCoreModel.Framework.CColumn;
import com.ErpCoreModel.Framework.CTable;
import com.ErpCoreModel.Framework.ColumnType;
import com.ErpCoreModel.Framework.DatabaseType;
import com.ErpCoreModel.Framework.DbParameter;
import com.ErpCoreModel.Framework.Util;
import com.ErpCoreModel.UI.CView;
import com.ErpCoreModel.UI.CViewDetail;
import com.ErpCoreModel.UI.CViewFilterMgr;
import com.ErpCoreWeb.Common.Global;
import com.mongodb.BasicDBObject;

/**
 * Servlet implementation class MasterDetailView
 */
@WebServlet("/MasterDetailView")
public class MasterDetailView extends HttpServlet {
	private static final long serialVersionUID = 1L;

	HttpServletRequest request;
	HttpServletResponse response;

    public CUser m_User = null;
    public CTable m_Table = null;
    public UUID m_guidParentId = Util.GetEmptyUUID();
    public CView m_View = null;
    AccessType m_ViewAccessType = AccessType.forbide;
    AccessType m_TableAccessType = AccessType.forbide;
    //受限的字段：禁止或者只读权限
    Map<UUID, AccessType> m_sortRestrictColumnAccessType = new HashMap<UUID, AccessType>();
    Map<UUID, AccessType> m_sortDetailRestrictColumnAccessType = new HashMap<UUID, AccessType>();

    /**
     * @see HttpServlet#HttpServlet()
     */
    public MasterDetailView() {
        super();
        // TODO Auto-generated constructor stub
    }

    //初始化变量
    void initData()
    {
        if (request.getSession().getAttribute("User") == null)
        {
            try {
				response.sendRedirect("../Login.jsp");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            return ;
        }
		try {
			m_User = (CUser) request.getSession().getAttribute("User");

			String vid = request.getParameter("vid");
			if (Global.IsNullParameter(vid)) {
				response.getWriter().close();
			}
			m_View = (CView) Global.GetCtx(this.getServletContext())
					.getViewMgr().Find(Util.GetUUID(vid));
			if (m_View == null) {
				response.getWriter().close();
			}
			m_Table = (CTable) Global.GetCtx(this.getServletContext())
					.getTableMgr().Find(m_View.getFW_Table_id());

			String ParentId = request.getParameter("ParentId");
			if (!Global.IsNullParameter(ParentId))
				m_guidParentId = Util.GetUUID(ParentId);
			

	        //检查权限
	        if (!CheckAccess())
	        {
	        	response.getWriter().close();
	        }
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProc(request,response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doProc(request,response);
	}
	void doProc(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		this.request=request;
		this.response=response;

		response.setContentType("text/html;charset=UTF-8");
		request.setCharacterEncoding("UTF-8");

		//初始化变量
	    initData();
	    //
        String Action = request.getParameter("Action");
        if (Action == null) Action = "";

        if (Action.equalsIgnoreCase("GetData"))
        {
        	GetData();
            return ;
        }
        else if (Action.equalsIgnoreCase("GetDetail"))
        {
        	GetDetail();
            return ;
        }
        else if (Action.equalsIgnoreCase("Delete"))
        {
        	Delete();
            return ;
        }
		
	}

    //检查权限
    boolean CheckAccess()
    {
		try {
			// 判断视图权限
			m_ViewAccessType = m_User.GetViewAccess(m_View.getId());
			if (m_ViewAccessType == AccessType.forbide) {
				response.getWriter().print("没有视图权限！");
				return false;
			}

			// 判断表权限
			m_TableAccessType = m_User.GetTableAccess(m_Table.getId());
			if (m_TableAccessType == AccessType.forbide) {
				response.getWriter().print("没有表权限！");
				return false;
			} else if (m_TableAccessType == AccessType.read) {
			} else {
			}
			m_sortRestrictColumnAccessType = m_User
					.GetRestrictColumnAccessTypeList(m_Table);

			return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }

	void GetData()
    {
		int page = Integer.valueOf(request.getParameter("page"));
		int pageSize = Integer.valueOf(request.getParameter("pagesize"));

        CBaseObjectMgr BaseObjectMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(m_Table.getCode(), m_guidParentId);
        if (BaseObjectMgr == null)
        {
            BaseObjectMgr = new CBaseObjectMgr();
            BaseObjectMgr.TbCode = m_Table.getCode();
            BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());
        }

        String sData = "";
        List<CBaseObject> lstObj;
        if (Global.IsNullParameter(request.getParameter("Filter")) 
        		|| request.getSession().getAttribute("ViewFilterMgr") == null)
        {
            lstObj = BaseObjectMgr.FilterByView(m_View,m_User);
            //清空过滤条件
            request.getSession().setAttribute("ViewFilterMgr", null);
        }
        else
        {
            //过滤查询
            Map<UUID, CViewFilterMgr> sortObj = (Map<UUID, CViewFilterMgr>)request.getSession().getAttribute("ViewFilterMgr");
            if (sortObj.containsKey(m_View.getId()))
            {
                CViewFilterMgr ViewFilterMgr = sortObj.get(m_View.getId());
                lstObj = BaseObjectMgr.FilterByView(m_View, ViewFilterMgr,m_User);
            }
            else
                lstObj = BaseObjectMgr.FilterByView(m_View,m_User);
        }

        int totalPage = lstObj.size() % pageSize == 0 ? lstObj.size() / pageSize : lstObj.size() / pageSize + 1; // 计算总页数

        int index = (page - 1) * pageSize; // 开始记录数  
        for (int i = index; i < pageSize + index && i < lstObj.size(); i++)
        {
            CBaseObject obj = (CBaseObject)lstObj.get(i);

            String sRow="";
            for (CBaseObject objC : m_Table.getColumnMgr().GetList())
            {
                CColumn col = (CColumn)objC;
                //判断禁止权限字段
                if (m_sortRestrictColumnAccessType.containsKey(col.getId()))
                {
                    AccessType accessType = m_sortRestrictColumnAccessType.get(col.getId());
                    if (accessType == AccessType.forbide)
                    {
                        String sVal = "";
                        sRow += String.format("\"%s\":\"%s\",", col.getCode(), sVal);
                        continue;
                    }
                }
                //

                if (col.getColType() == ColumnType.object_type)
                {
                    String sVal = "";
                    if (obj.GetColValue(col) != null)
                        sVal = "long byte";
                    sRow += String.format("\"%s\":\"%s\",", col.getCode(), sVal);
                }
                else if (col.getColType() == ColumnType.ref_type)
                {
                    CTable RefTable = (CTable)Global.GetCtx(this.getServletContext()).getTableMgr().Find(col.getRefTable());
                    if (RefTable == null) continue;
                    CColumn RefCol = (CColumn)RefTable.getColumnMgr().Find(col.getRefCol());
                    CColumn RefShowCol = (CColumn)RefTable.getColumnMgr().Find(col.getRefShowCol());
                    Object objVal = obj.GetColValue(col);


                    String sVal = "";
                    UUID guidParentId = Util.GetEmptyUUID();
                    if (BaseObjectMgr.m_Parent != null && BaseObjectMgr.m_Parent.getId().equals((UUID)objVal))
                    {
                        Object objVal2 = BaseObjectMgr.m_Parent.GetColValue(RefShowCol);
                        if (objVal2 != null)
                            sVal = objVal2.toString();
                    }
                    else
                    {
                        CBaseObjectMgr objRefMgr = Global.GetCtx(this.getServletContext()).FindBaseObjectMgrCache(RefTable.getCode(), guidParentId);
                        if (objRefMgr != null)
                        {
                            CBaseObject objCache = objRefMgr.FindByValue(RefCol, objVal);
                            if (objCache != null)
                            {
                                Object objVal2 = objCache.GetColValue(RefShowCol);
                                if (objVal2 != null)
                                    sVal = objVal2.toString();
                            }
                        }
                        else
                        {
                            objRefMgr = new CBaseObjectMgr();
                            objRefMgr.TbCode = RefTable.getCode();
                            objRefMgr.Ctx = Global.GetCtx(this.getServletContext());

                            if (objRefMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                            {
                            	BasicDBObject query = new BasicDBObject();  
                                query.put(RefCol.getBsonCode(), obj.GetColValue(col));
                                List<CBaseObject> lstObj2 = objRefMgr.GetList(query, null, 0, 0);
                                if (lstObj2.size() > 0)
                                {
                                    CBaseObject obj2 = lstObj2.get(0);
                                    Object objVal2 = obj2.GetColValue(RefShowCol);
                                    if (objVal2 != null)
                                        sVal = objVal2.toString();
                                }
                            }
                            else
                            {
	                            String sWhere = String.format(" %s=%s", RefCol.getCode(),obj.GetColSqlValue(col));
	                            List<CBaseObject> lstObj2 = objRefMgr.GetList(sWhere);
	                            if (lstObj2.size() > 0)
	                            {
	                                CBaseObject obj2 = lstObj2.get(0);
	                                Object objVal2 = obj2.GetColValue(RefShowCol);
	                                if (objVal2 != null)
	                                    sVal = objVal2.toString();
	                            }
                            }
                        }
                    }
                    sRow += String.format("\"%s\":\"%s\",", col.getCode(), sVal);
                }
                else
                {
                    String sVal = "";
                    Object objVal = obj.GetColValue(col);
                    if (objVal != null)
                        sVal = objVal.toString();
                    //转义特殊字符
                    StringBuffer temp=new StringBuffer();
                    temp.append(sVal);
                    com.ErpCoreWeb.Common.Util.ConvertJsonSymbol(temp);
                    sVal=temp.toString();
                    sRow += String.format("\"%s\":\"%s\",", col.getCode(), sVal);
                }

            }
    		if (sRow.endsWith(","))
    			sRow = sRow.substring(0, sRow.length() - 1);
            sRow = "{" + sRow + "},";
            sData += sRow;
        }
		if (sData.endsWith(","))
			sData = sData.substring(0, sData.length() - 1);
        sData = "[" + sData + "]";
        String sJson = String.format("{\"Rows\":%s,\"Total\":\"%d\"}"
            , sData, lstObj.size());

        try {
			response.getWriter().print(sJson);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    void GetDetail()
    {
		try {
			String pid = request.getParameter("pid");
			if (Global.IsNullParameter(pid))
				return;
			CViewDetail vd = (CViewDetail) m_View.getViewDetailMgr()
					.GetFirstObj();
			CTable table = (CTable) Global.GetCtx(this.getServletContext())
					.getTableMgr().Find(vd.getFW_Table_id());

			// 判断表权限
			AccessType tableAccessType = m_User.GetTableAccess(table.getId());
			if (tableAccessType == AccessType.forbide) {
				response.getWriter().print("没有表权限！");
				return;
			} else if (tableAccessType == AccessType.read) {
			} else {
			}
			m_sortDetailRestrictColumnAccessType = m_User
					.GetRestrictColumnAccessTypeList(table);
			//
			CBaseObjectMgr BaseObjectMgr = Global.GetCtx(
					this.getServletContext()).FindBaseObjectMgrCache(
					m_Table.getCode(), Util.GetUUID(pid));
			if (BaseObjectMgr == null) {
				BaseObjectMgr = new CBaseObjectMgr();
				BaseObjectMgr.TbCode = table.getCode();
				BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());

				CColumn colF = (CColumn) table.getColumnMgr().Find(
						vd.getForeignKey());
				if (colF == null)
					return;
				if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put(colF.getBsonCode(), pid);
                    BaseObjectMgr.GetList(query, null, 0, 0);
                }
				else
				{
					String sWhere0 = String.format(" %s='%s'", colF.getCode(), pid);
					BaseObjectMgr.GetList(sWhere0);
				}
			}
			List<CBaseObject> lstObj = BaseObjectMgr.GetList();

			String sData = "";
			for (CBaseObject obj : lstObj) {
				String sRow = "";
				for (CBaseObject objC : table.getColumnMgr().GetList()) {
					CColumn col = (CColumn) objC;
					// 判断禁止权限字段
					if (m_sortDetailRestrictColumnAccessType.containsKey(col
							.getId())) {
						AccessType accessType = m_sortDetailRestrictColumnAccessType
								.get(col.getId());
						if (accessType == AccessType.forbide) {
							String sVal = "";
							sRow += String.format("\"%s\":\"%s\",",
									col.getCode(), sVal);
							continue;
						}
					}
					//

					if (col.getColType() == ColumnType.object_type) {
						String sVal = "";
						if (obj.GetColValue(col) != null)
							sVal = "long byte";
						sRow += String.format("\"%s\":\"%s\",", col.getCode(),
								sVal);
					} else if (col.getColType() == ColumnType.ref_type) {
						CTable RefTable = (CTable) Global
								.GetCtx(this.getServletContext()).getTableMgr()
								.Find(col.getRefTable());
						if (RefTable == null)
							continue;
						CColumn RefCol = (CColumn) RefTable.getColumnMgr()
								.Find(col.getRefCol());
						CColumn RefShowCol = (CColumn) RefTable.getColumnMgr()
								.Find(col.getRefShowCol());
						Object objVal = obj.GetColValue(col);

						String sVal = "";
						UUID guidParentId = Util.GetEmptyUUID();
						if (BaseObjectMgr.m_Parent != null
								&& BaseObjectMgr.m_Parent.getId().equals(
										(UUID) objVal)) {
							Object objVal2 = BaseObjectMgr.m_Parent
									.GetColValue(RefShowCol);
							if (objVal2 != null)
								sVal = objVal2.toString();
						} else {
							CBaseObjectMgr objRefMgr = Global.GetCtx(
									this.getServletContext())
									.FindBaseObjectMgrCache(RefTable.getCode(),
											guidParentId);
							if (objRefMgr != null) {
								CBaseObject objCache = objRefMgr.FindByValue(
										RefCol, objVal);
								if (objCache != null) {
									Object objVal2 = objCache
											.GetColValue(RefShowCol);
									if (objVal2 != null)
										sVal = objVal2.toString();
								}
							} else {
								objRefMgr = new CBaseObjectMgr();
								objRefMgr.TbCode = RefTable.getCode();
								objRefMgr.Ctx = Global.GetCtx(this
										.getServletContext());

								if (objRefMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
	                            {
	                            	BasicDBObject query = new BasicDBObject();  
	                                query.put(RefCol.getBsonCode(), obj.GetColValue(col));
	                                List<CBaseObject> lstObj2 = objRefMgr.GetList(query, null, 0, 0);
	                                if (lstObj2.size() > 0)
	                                {
	                                    CBaseObject obj2 = lstObj2.get(0);
	                                    Object objVal2 = obj2.GetColValue(RefShowCol);
	                                    if (objVal2 != null)
	                                        sVal = objVal2.toString();
	                                }
	                            }
	                            else
	                            {
		                            String sWhere = String.format(" %s=%s", RefCol.getCode(),obj.GetColSqlValue(col));
		                            List<CBaseObject> lstObj2 = objRefMgr.GetList(sWhere);
		                            if (lstObj2.size() > 0)
		                            {
		                                CBaseObject obj2 = lstObj2.get(0);
		                                Object objVal2 = obj2.GetColValue(RefShowCol);
		                                if (objVal2 != null)
		                                    sVal = objVal2.toString();
		                            }
	                            }
							}
						}
						sRow += String.format("\"%s\":\"%s\",", col.getCode(),
								sVal);
					} else {
						String sVal = "";
						Object objVal = obj.GetColValue(col);
						if (objVal != null)
							sVal = objVal.toString();
						// 转义特殊字符
						StringBuffer temp = new StringBuffer();
						temp.append(sVal);
						com.ErpCoreWeb.Common.Util.ConvertJsonSymbol(temp);
						sVal = temp.toString();
						sRow += String.format("\"%s\":\"%s\",", col.getCode(),
								sVal);
					}

				}
				if (sRow.endsWith(","))
					sRow = sRow.substring(0, sRow.length() - 1);
				sRow = "{" + sRow + "},";
				sData += sRow;
			}
			if (sData.endsWith(","))
				sData = sData.substring(0, sData.length() - 1);
			sData = "[" + sData + "]";
			String sJson = String.format("{\"Rows\":%s,\"Total\":\"%d\"}",
					sData, lstObj.size());

			response.getWriter().print(sJson);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    void Delete()
    {
		try {
			String delid = request.getParameter("delid");
			if (Global.IsNullParameter(delid)) {
				response.getWriter().print("请选择记录！");
				return;
			}
			if (m_ViewAccessType != AccessType.write) {
				response.getWriter().print("没有写权限！");
				return;
			}
			if (m_TableAccessType != AccessType.write) {
				response.getWriter().print("没有写权限！");
				return;
			}

			CBaseObjectMgr BaseObjectMgr = Global.GetCtx(
					this.getServletContext()).FindBaseObjectMgrCache(
					m_Table.getCode(), m_guidParentId);
			if (BaseObjectMgr == null) {
				BaseObjectMgr = new CBaseObjectMgr();
				BaseObjectMgr.TbCode = m_Table.getCode();
				BaseObjectMgr.Ctx = Global.GetCtx(this.getServletContext());
				if (BaseObjectMgr.Ctx.getMainDB().m_DbType == DatabaseType.MongoDb)
                {
                	BasicDBObject query = new BasicDBObject();  
                    query.put("_id", delid);
                    BaseObjectMgr.GetList(query, null, 0, 0);
                }
				else
				{
					String sWhere = String.format(" id='%s'", delid);
					BaseObjectMgr.GetList(sWhere);
				}
			}
			if (!BaseObjectMgr.Delete(Util.GetUUID(delid))) {
				response.getWriter().print(BaseObjectMgr.Ctx.LastError);
				return;
			}

			if (!BaseObjectMgr.Save(true)) {
				response.getWriter().print("删除失败！");
				return;
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
}
